/*
 * Copyright (c) United Binary LLC.  All rights reserved.
 * 
 * This code is licensed under the MIT License
 * 
 * SEE: http://harnessit.codeplex.com/license
 * 
 */
using System;
using System.Diagnostics;

using UnitedBinary.UnitTests.Framework;
using UnitedBinary.UnitTests.Framework.TestItems;

namespace UnitedBinary.HarnessIt.TestEngine.PortableTestItems
{
	/// <summary>
	/// Summary description for PortableExecutionResult.
	/// </summary>
	[Serializable]
	public class PortableExecutionResult
	{
		private PortableTestObject [] testObjects = new PortableTestObject [0];
		private bool success = true;
		private string errorMessage = "No Errors.";
		private TestException [] testExceptions = new TestException [0];

		public PortableExecutionResult()
		{
		}

		public PortableExecutionResult(TestMethodRecord tmr)
		{
			Initialize(tmr);
		}

		public void Initialize(TestMethodRecord tmr)
		{
			Success = true;
			PortableTestObject [] portableResults = new PortableTestObject [tmr.TestObjectCount];
			for (int i=0; i < tmr.TestObjectCount; i++)
			{
				portableResults[i] = new PortableTestObject();
				PortableTestObject pto = portableResults[i];
				TestObject to = tmr.GetResult(i);
			
				if (to.TestObjectType == TestObjectTypes.TestResult)
				{
					pto.Type		= PortableTestObject.TestObjectType.Result;
			
					TestResult tr	= (TestResult)to;
					pto.Description = tr.Description;
					pto.Success		= tr.Success;
				}
				else if (to.TestObjectType == TestObjectTypes.TestComment)
				{
					pto.Type		= PortableTestObject.TestObjectType.Comment;
			
					TestComment tc	= (TestComment)to;
					pto.Comment		= tc.Comment;
				}
			}
			
			TestObjects = portableResults;
			this.TestExceptions = tmr.TestExceptions;
		}

		public void AppendTestObjects(PortableTestObject [] PTOs)
		{
			try
			{
				PortableTestObject [] PTOs1 = this.TestObjects;
				PortableTestObject [] PTOs2 = PTOs;

				PortableTestObject [] newPTOArray = new PortableTestObject[PTOs1.Length + PTOs2.Length];

				Array.Copy(PTOs1, 0, newPTOArray, 0, PTOs1.Length);
				Array.Copy(PTOs2, 0, newPTOArray, PTOs1.Length, PTOs2.Length);

				this.testObjects = newPTOArray;
			}
			catch (Exception e)
			{
				System.Diagnostics.Trace.WriteLine(e.ToString());
			}
		}

		public TestMethodRecord GenerateRecord()
		{
			TestMethodRecord tmr = new TestMethodRecord();
			tmr.HasRun = true;

			PortableTestObject [] PTOs = TestObjects;
			int length = PTOs.Length;

			for (int i=0; i < length; i++)
			{
				PortableTestObject pto = PTOs[i];
				switch(pto.Type)
				{
					case PortableTestObject.TestObjectType.Result:
						tmr.RunTest(pto.Success, pto.Description);
						break;
					case PortableTestObject.TestObjectType.Comment:
						tmr.WriteLine(pto.Comment);
						break;
				}
			}

			foreach (TestException te in this.TestExceptions)
			{
				tmr.AddTestException(te);
			}

			return tmr;
		}

		public void EmitTraceOutput()
		{
			PortableTestObject [] PTOs = this.TestObjects;
			foreach(PortableTestObject pto in PTOs)
			{
				if (pto.Type == PortableTestObject.TestObjectType.Trace)
				{
					Trace.Write(pto.Comment);
				}
			}
		}
		
		public PortableTestObject [] TestObjects
		{
			get
			{
				return testObjects;
			}
			set
			{
				testObjects = value;
			}
		}

		public string ErrorMessage
		{
			get
			{
				return errorMessage;
			}
			set
			{
				errorMessage = value;
				if (value == null)
				{
					errorMessage = "";
				}
			}
		}

		public bool Success 
		{
			get
			{
				return success;
			}
			set
			{
				success = value;
			}
		}

		public TestException [] TestExceptions
		{
			get
			{
				return testExceptions;
			}
			set
			{
				testExceptions = value;
				if (value == null)
				{
					testExceptions = new TestException [0];
				}
			}
		}
	}
}
